android 实际项目中经常使用到webview,在使用过程中会遇到的一些问题。这些问题主要是webview在使用过程中我已经趟过的坑,希望通过这篇文章的介绍能够帮助大家更好的使用webview。
webview的性能优化
webview注入cookie信息
webview退出activity异常
webview中native与js交互
webview下载文件
腾讯X5优势
webview的性能问题
在讲解webview的性能问题之前,我们先来了解一下android webview的缓存机制。
- Android WebView缓存机制
WebView中存在着两种缓存:网页数据缓存(网页数据,url等)、H5缓存(H5代码缓存数据)
不同的缓存数据会保存在不同的文件目录下,这里引用一下其他blog的说法:
当我们加载Html时候,会在我们data/应用package下生成database与cache两个文件夹:
我们请求的Url记录是保存在webviewCache.db里,而url的内容是保存在webviewCache文件夹下。
webview中也是可以设置缓存是否可用的,一般是通过WebSettings对象设置,下面我们就来看一下WebSettings对象的使用。
- android中webview组件有几个重要的方法
|
|
可以看到我们可以使用WebSettings对象设置缓存是否可用,缓存DB是否可用等。我们需要首先确保这里设置了缓存可用,才可以继续设置使用何种缓存策略。
下面我们来看一下webview的五种缓存模式:
LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
LOAD_DEFAULT: 根据cache-control决定是否从网络上取数据。
LOAD_CACHE_NORMAL: API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式
LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
- 几种缓存方式的实现
(1)使用LOAD_CACHE_ELSE_NETWORK缓存模式,这样需要在APP退出的时候清除webview缓存,但是这样做有一个弊端就是如果当前App已经是打开状态,网页内容有更新的话不会看到;
(2)使用LOAD_DEFAULT这种缓存方式,数据从缓存中获取还是从网络中获取根据H5页面的参数判断,这样做的好处是可以动态的处理更新内容;
- 设置缓存
|
|
- 退出App时清除缓存
|
|
- 其他的缓存策略
网页在加载的时候暂时不加载图片,当所有的HTML标签加载完成时在加载图片具体的做法如下初始化webview的时候设置不加载图片
|
|
然后在html标签加载完成之后在加载图片内容:
O(∩_∩)O哈哈~,这样做的好处就是可以给人的感觉网页加载速度很快…
- 将网页内容中需要的js,css引用文件保存在App本地
加载网页内容时,在加载完成html后替换页面内容引用的地址改为本地的资源文件地址,这样可以直接加载本地的资源文件加快资源的访问速度,目前主流的新闻客户端访问webview时多采用这种方式。
好吧,讲解完了webview的性能优化问题之后我们在讲解一下如何在H5页面种入Cookie信息。
H5页面种入Cookie问题
app中存在webview控件,既可以通过Native与js代码交互的方式实现信息的交互也可以通过cookie的方式与实现Native与H5端的交互,查询的好多资料各种各样的实现方式都有,最终不断尝试基本实现了需求,现说明一下最终的实现方式;
|
|
其中CookieManager是cookie的管理对象,主要实现对网页cookie的注入与清除等工作。注入字符串的形式是:key=value;domain=url的形式(其中url为需要注入cookie的url链接地址)
那么如何移除cookie呢?
|
|
一般情况下都是在打开H5页面的时候种入Cookie信息,然后在离开H5页面的时候清除cookie信息。当然了通过cookie实现native与js的交互只是实现信息交互的一种方式,我们还可以通过js与java代码相互调用的方式实现相互交互,文章的后面会有介绍。
而下面我们再来讲解一下activity退出时webview报错的问题。
Activity退出时webview报错的问题
前段时间在调试代码的时候,有一段关于webview的代码,即退出Fragment的时候清除webview,这时候大部分手机是没有问题的,但是有一些手机上就报错,而其报错信息是:
|
|
程序也没有异常退出之类的动作,清除webview的代码是这样写的:
|
|
这个错误大概的意思是:当你结束webview的时候,webview还依附在其父控件之下,应当在调用webview.destory()方法之前接触他们之间的依附关系,那么既然错误提示信息已经很明显了,我们就根据错误信息尝试着首先执行webview父控件的清除工作,然后在执行webview控件的清除操作,所以代码中应该这样实现:
|
|
这样经过修改之后特定机型上关于webview的错误就不在了。
webview中实现Native与js相互调用
上面我们介绍的通过cookie实现android native与H5的信息交互只是一种方式,我们也可以通过java代码与js代码直接相互调用的方式实现android native与H5信息的相互,这里简单的介绍一下使用方式
- native代码调用H5的js代码
(1)在H5页面中添加一个js函数
|
|
(2)在Native中通过java代码调用
若这时候H5页面已经被加载到webview中,则可以通过java代码直接调用js函数:
|
|
是的,没错就是这么简单,这样就实现了java代码对js代码的调用,但是需要指出的是这里无法调用含有返回值的js函数。
- js代码调用java函数
(1)首先在java端编写能够被js代码调用的java函数
- native方法的实现1234567891011/*** 自定义实现的native函数,可被js代码调用*/class JsInteration {...@JavascriptInterfacepublic void toastMessage(String message) {Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show();}...}
(2)在native中注入本地方法,供js调用;
|
|
(3)在js代码中调用java代码:
|
|
以上就是webview中使用js代码与java代码相互调用的简单例子。
webview下载文件
在使用webview开发中还遇到一个问题,app中webview中存在下载链接,但是在手机浏览器中点击下载是没有问题的,在webview中怎么都不好使。查询了好久,原来是因为WebView默认没有开启文件下载的功能,如果要实现文件下载的功能,需要设置WebView的DownloadListener,通过实现自己的DownloadListener来实现文件的下载。
- 设置webview的setDownloadListener方法
|
|
- 重写onDownloadStart回调方法,实现下载文件的逻辑
比如在浏览器中实现下载:
|
|
这样我们的webview中如果包含了下载链接就可以通过打开浏览器的方式实现下载了。
注:个人感觉webview没有默认实现下载链接的功能更多的可能是考虑权限,安全方面的问题。
腾讯X5优势:
1) 速度快:相比系统webView的网页加载速度有近30%的提升。
2) 省流量:云端优化技术使流量节省20%
3) 更安全:24小时安全问题解决机制
4) 更稳定:经过亿级用户的使用考验,CRASH率0.15%
5) 集成强大的视频播放器,支持各种视频格式直接打开
6) 适屏排版、字体设置等浏览增强功能的提供
7) Html5更完整支持。
8) 无系统内核的碎片化问题,更少的兼容性问题
总结:
webview的有一定的性能问题,可以设置不同的缓存策略提高webview的加载速率
webview与native可以通过cookie的方式实现信息交互
webview下载文件,需要重写自己的native的DownloadListener类,以及其回调方法
实现Native与H5端信息的交互既可以使用cookie的方式也可以通过java代码与js代码实现
原生的webview在不同手机上可能存在不同的表现,建议可以使用腾讯的X5浏览服务屏蔽的不同手机的差别,添加了不少特色的小功能